/*
Simple Forum Auto Poster.
Copyright (C) 2011 Gianni Van Hoecke.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package domain.forumdata.forums;

import domain.DomainController;
import domain.forumdata.Category;
import domain.forumdata.Forum;
import domain.forumdata.ForumCategory;
import domain.forumdata.SupportedForums;
import domain.forumdata.tag.Tag;
import domain.net.HTMLParser;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.text.html.HTML.Attribute;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import persistence.net.Client;

/**
 *
 * @author Gianni Van Hoecke <gianni.vh@gmail.com>
 * Represents ForumW.org
 *
 * @deprecated ForumW.org no longer exists... :( Keeping the code for reference though.
 */
public class ForumW extends Forum
{
    public static final String FORUM_BASE_URL = "http://forumw.org/";
    public static final String LOGIN_URL = "http://forumw.org/ucp.php?mode=login";
    public static final String LOGIN_SUCCEED_CHECK = "You have been successfully logged in";
    public static final String POST_SUCCEED_CHECK = "This message has been posted successfully";
    public static final String VIEWTOPIC_INDICATOR = "./viewtopic.php?f=";

    private Client client;

    private String sid;

    /**
     * Default constructor. Initializes a new forum of type ForumW.
     * @param forumName The name for the forum.
     * @param username The username.
     * @param password The password.
     * @param categories A list of assigned categories.
     */
    public ForumW(String forumName, String username, char[] password, ArrayList<ForumCategory> categories)
    {
        super(SupportedForums.SUPPORTED_FORUMS[1], forumName, LOGIN_URL, username, password, categories);
        sid = null;
    }

    /**
     * Starts posting to the forum.
     * @param cat The category to post to.
     * @param topicTitle The topic title of the new post.
     * @param topicSubtitle The topic subtitle or small description of the new post.
     * @param tag The tag to use.
     * @param post The post body of the new post.
     * @return True if the message has been posted, false otherwise.
     */
    @Override
    public boolean doPost(Category cat, String topicTitle, String topicSubtitle, Tag tag, String post)
    {
        //Create new client
        this.client = new Client();

        //Login
        DomainController.getInstance().getLogger().log(Level.INFO, "Logging in...");

        if(this.login())
        {
            //Get the correct new topic link
            String newTopicURL = "";
            for(ForumCategory fc : this.getCategories())
            {
                if(fc.getCategory().getName().equals(cat.getName()))
                {
                    newTopicURL = fc.getUrl();
                    break;
                }
            }

            //Post!
            DomainController.getInstance().getLogger().log(Level.INFO, "Creating new topic...");
            return this.post(newTopicURL, topicTitle, topicSubtitle, tag, post);
        }
        else
        {
            DomainController.getInstance().getLogger().log(Level.WARNING, "Login failed!");
        }
        return false;
    }

    /**
     * Tries to login at this forum.
     * @return True if the login was successful, false oterhwise.
     */
    private boolean login()
    {
        try
        {
            //We need to get the SID
            //<input type="hidden" value="86e10d9a26984dd360b329d9a461af0e" name="sid">
            this.client.doGet(LOGIN_URL);
            String content = this.client.getResponseContent();
            List<String> sidl = HTMLParser.extractValueFromTag(new StringReader(content),
                                                        javax.swing.text.html.HTML.Tag.INPUT,
                                                        Attribute.NAME,
                                                        "sid",
                                                        Attribute.VALUE);
            this.sid = sidl.get(0);

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("username", this.getUsername()));
            nameValuePairs.add(new BasicNameValuePair("password", new String(this.getPassword())));
            nameValuePairs.add(new BasicNameValuePair("autologin", "1"));
            nameValuePairs.add(new BasicNameValuePair("redirect", "index.php"));
            nameValuePairs.add(new BasicNameValuePair("sid", this.sid));
            nameValuePairs.add(new BasicNameValuePair("login", "Login"));
            this.client.doPost(ForumW.LOGIN_URL, nameValuePairs);

            //Check if the login has succeeded.
            if(this.client.getResponseContent().contains(ForumW.LOGIN_SUCCEED_CHECK))
                return true;
            else
                return false;
        }
        catch(Exception e)
        {
            DomainController.getInstance().getLogger().log(Level.SEVERE, "Login failed! ({0})", e.getMessage());
            return false;
        }
    }

    /**
     * Tries to post a new topic at this forum.
     * When successful, the method tries to find the link of the new topic and stores it.
     * @param url The url of the "new topic".
     * @param topicTitle The title for the new topic.
     * @param topicSubtitle The subtitle or small description for the new topic.
     * @param tag The tag to use.
     * @param post The message for the new topic.
     * @return True if the message has been posted, false otherwise.
     */
    private boolean post(String url, String topicTitle, String topicSubtitle, Tag tag, String post)
    {
        try
        {
            //icon=27
            //subject=Subject
            //message=message+body%21
            //attach_sig=on
            //notify=on
            //form_token=a9023565818abea2a81808d750ee6a493697778a
            //lastclick=1305403155
            //creation_time=1305403155
            //preview=Preview
            this.client.doGet(url);
            String content = this.client.getResponseContent();

            List<String> form_token = HTMLParser.extractValueFromTag(new StringReader(content),
                                                        javax.swing.text.html.HTML.Tag.INPUT,
                                                        Attribute.NAME,
                                                        "form_token",
                                                        Attribute.VALUE);

            List<String> lastclick = HTMLParser.extractValueFromTag(new StringReader(content),
                                                        javax.swing.text.html.HTML.Tag.INPUT,
                                                        Attribute.NAME,
                                                        "lastclick",
                                                        Attribute.VALUE);

            List<String> creationtime = HTMLParser.extractValueFromTag(new StringReader(content),
                                                        javax.swing.text.html.HTML.Tag.INPUT,
                                                        Attribute.NAME,
                                                        "creation_time",
                                                        Attribute.VALUE);

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

            nameValuePairs.add(new BasicNameValuePair("icon", tag.getSynonyms()[1]));
            nameValuePairs.add(new BasicNameValuePair("subject", topicTitle));
            nameValuePairs.add(new BasicNameValuePair("message", post));
            nameValuePairs.add(new BasicNameValuePair("attach_sig", "on"));
            nameValuePairs.add(new BasicNameValuePair("notify", "on"));
            nameValuePairs.add(new BasicNameValuePair("form_token", form_token.get(0)));
            nameValuePairs.add(new BasicNameValuePair("lastclick", lastclick.get(0)));
            nameValuePairs.add(new BasicNameValuePair("creation_time", creationtime.get(0)));
            nameValuePairs.add(new BasicNameValuePair("post", "Submit"));
            //nameValuePairs.add(new BasicNameValuePair("preview", "Preview"));

            //ForumW.org has a server side validation on how much time has passed
            //So we'll sleep for 5 seconds, just to be sure.
            Thread.sleep(5000);

            this.client.doPost(url, nameValuePairs);

            if(this.client.getResponseContent().contains(ForumW.POST_SUCCEED_CHECK))
            {
                //Get the topic url.
                //<a href="./viewtopic.php?f=65&amp;t=3481101">View your submitted message</a>
                //href = ./viewtopic.php?f=65&amp;t=3481101
                List<String> hrefs = HTMLParser.getHREF(new StringReader(this.client.getResponseContent()));
                String link = ForumW.FORUM_BASE_URL;
                for(String s : hrefs)
                {
                    if(s != null && s.contains(ForumW.VIEWTOPIC_INDICATOR))
                    {
                        link += s.substring(2); //Remove the './'
                        break;
                    }
                }
                DomainController.getInstance().getLastPostTopicURLResults().add(link);
                DomainController.getInstance().getLogger().log(Level.INFO, "SUCCESS! Got link: {0}", link);
                return true;
            }
            else
            {
                DomainController.getInstance().getLogger().log(Level.WARNING, "Posting failed!");
                DomainController.getInstance().getLogger().log(Level.INFO, "Got response: {0}", this.client.getResponseContent());
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
            DomainController.getInstance().getLogger().log(Level.SEVERE, "Posting failed! ({0})", e.getMessage());
        }
        return false;
    }

    @Override
    public boolean canLogin()
    {
        this.client = new Client();
        return this.login();
    }
}